<!--
 * @Author: Xujianchen
 * @Date: 2024-12-23 14:59:48
 * @LastEditors: Xujianchen
 * @LastEditTime: 2024-12-31 16:28:05
 * @Description: better-scroll 下拉刷新
-->
<template>
  <Wrapper>
    <div class="pulldown">
      <div ref="wrapperRef" class="pulldown-wrapper">
        <div class="pulldown-scroller">
          <div class="pulldown-scroller-wrapper">
            <div v-show="beforePullDown">
              <span>下拉刷新</span>
            </div>
            <div v-show="!beforePullDown">
              <div v-show="isPullingDown">
                <span>加载中...</span>
              </div>
              <div v-show="!isPullingDown">
                <span>刷新成功</span>
              </div>
            </div>
          </div>
          <ul class="pulldown-list">
            <li v-for="i of dataList" :key="i" class="pulldown-list-item">
              {{ `I am item ${i} ` }}
            </li>
          </ul>
        </div>
      </div>
    </div>
  </Wrapper>
</template>

<script setup>
import BScroll from '@better-scroll/core'
import PullDown from '@better-scroll/pull-down'

BScroll.use(PullDown)

let STEP = 0
const bscroll = ref(null)
const wrapperRef = ref(null)
const dataList = ref(generateData())
const isPullingDown = ref(false)
const beforePullDown = ref(true)
const REQUEST_TIME = 1000
const TIME_BOUNCE = 800
const THRESHOLD = 70
const STOP = 56

onMounted(() => initBScroll())

function initBScroll() {
  const bs = (bscroll.value = new BScroll(wrapperRef.value, {
    bounceTime: TIME_BOUNCE,
    pullDownRefresh: {
      threshold: THRESHOLD,
      stop: STOP,
    },
  }))

  bs.on('pullingDown', pullingDownHandler)
  bs.on('scroll', (pos) => console.log(pos.y))
  bs.on('scrollEnd', (e) => console.log('scrollEnd', e))
}

// 开始下拉刷新
async function pullingDownHandler() {
  console.log('trigger pullDown')
  beforePullDown.value = false
  isPullingDown.value = true
  STEP += 1

  await requestData()

  isPullingDown.value = false
  finishPullDown()
}

// 下拉刷新完成
async function finishPullDown() {
  const bs = bscroll.value
  bs.finishPullDown()
  setTimeout(() => {
    beforePullDown.value = true
    bs.refresh()
  }, TIME_BOUNCE + 100)
}

async function requestData() {
  try {
    const newData = await ajaxGet()
    dataList.value = newData.concat(dataList.value)
  } catch (err) {
    console.log(err)
  }
}

function ajaxGet() {
  return new Promise((resolve) => {
    setTimeout(() => {
      const dataList = generateData()
      resolve(dataList)
    }, REQUEST_TIME)
  })
}

function generateData() {
  const BASE = 30
  const begin = BASE * STEP
  const end = BASE * (STEP + 1)
  let ret = []
  for (let i = end; i > begin; i--) {
    ret.push(i)
  }
  return ret
}
</script>

<style scoped lang="scss">
.pulldown {
  height: 500px;

  &-wrapper {
    position: relative;
    height: 100%;
    padding: 0 $space-small-s;
    border: 1px solid #ccc;
    overflow: hidden;
  }

  &-list {
    padding: 0;
  }

  &-list-item {
    padding: $space-small-s 0;
    list-style: none;
    border-bottom: 1px solid #ccc;
  }

  &-scroller-wrapper {
    position: absolute;
    width: 100%;
    padding: $space-medium-s;
    box-sizing: border-box;
    transform: translateY(-100%) translateZ(0);
    text-align: center;
    color: #999;
  }
}
</style>
